import os
import wsgiref.handlers

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp

#from google.appengine.ext.webapp import template
#from google.appengine.ext.db import djangoforms

from mako.template import Template
from mako.lookup import TemplateLookup

#import sys
#reload(sys); sys.setdefaultencoding('utf-8')


class AppModel(db.Expando):
	""" Superclass of all application Models. Defines properties for all
		Models """
	user = db.UserProperty(auto_current_user_add = True)
	created = db.DateProperty(auto_now_add =True)
	updated = db.DateProperty(auto_now = True)
	
class Feed(AppModel):
	""" Describes a user's feed. Defines only application data for the 
		feed. All actual feed data is optional, and represented by 
		Expando properties. """
	url = db.LinkProperty()
	refreshed = db.DateProperty()

#class FeedForm(djangoforms.ModelForm):
#	class Meta:
#		model = Feed
#		exclude = ['user', 'refreshed']
	
class Entry(AppModel):
	""" Describes an entry in a feed. Defines only data which the 
		application creates for the entry. All actual entry data is 
		optional, and represented by Expando properties. """
	feed = db.ReferenceProperty(Feed)

def render(response, name, context, format=None):
	"Renders a template and writes it to the response. To keep DRY."
	
	context['user'] = users.get_current_user()
	
	if context['user']:
		context['user_action'] = 'logout'
		context['user_link'] = users.create_logout_url("/")
	else:
		context['user_action'] = 'login'
		context['user_link'] = users.create_login_url("/")
	
	# set default format
	if format is None:
		format = 'html'
		
	# render template
	#path = os.path.join(os.path.dirname(__file__), 'templates', name+'.'+format)
	mako = Template(
		filename = os.path.join(os.path.dirname(__file__), 'tpl', name+'.'+format),
		lookup = TemplateLookup(directories = ['/'])
	)
	response.out.write(mako.render(**context))

class HomeHandler(webapp.RequestHandler):
  """ Just says hi """
  
  context = {'title':"Home"}
  
  def get(self):
	
	import feedparser
	from google.appengine.api import urlfetch
	url = "http://blog.codery.com/rss"
	result = urlfetch.fetch(url)
	feed = feedparser.parse(result.content)
	self.context['feed'] = feed
	render(self.response, 'home', self.context)
		
class FeedHandler(webapp.RequestHandler):
	""" Handles users' feeds """
	
	context = {'title':'Feeds'}
	
	def get(self, key, format): 
		""" displays feeds """
		
		if key is None:
			self.context['FeedForm'] = FeedForm()
			
			# get all of the user's feeds from memcache
			# if no value in memcache, 
			# get all feeds from DataStore
			self.context['feeds'] = db.GqlQuery("SELECT * FROM Feed ORDER BY created DESC LIMIT 10")
			# save them in memcache
			# tell the template what page to start from?
			# tell the template what value to sort by?
			# tell the template what property columns to display?
			render(self.response, 'index', self.context, format)
		else:
			# get the record from memcache
			# if the record wasn't found in memcache
			# load the record fromthe DataStore
			# save the data in memcache
			# set the data in the context
			# tell the template which properties to display
			# tell the template which associated models to include
			self.context['format'] = format
			self.context['key'] = key
			q = db.GqlQuery("SELECT * FROM Feed WHERE key = :1", key)
			data = db.get(key)
			
			self.context['data'] = data
			render(self.response, 'view', self.context, format)
		
	def post(self, key, format): 
		""" Creates a feed """
		
		if key is None: 
			if users.get_current_user():
				data = FeedForm(data=self.request.POST)
				if data.is_valid():
					# Save the data, and redirect to the view page
					entity = data.save(commit=False)
					entity.put()
					self.redirect('/feeds/'+str(entity.key())+'.html')
				else:
					# Reprint the form
					self.context['FeedForm'] = data
					render(self.response, 'index', self.context, format)
			else:
				raise Exception("user not logged in")
		else:
			raise Exception("cannot post to a key")
				
		
	def put(self, key, format): 
		"changes a feed"
		
	def delete(self, key, format): 
		"deletes a feed"

class EntryHandler(webapp.RequestHandler):
	"Handles an entry in a feed"
	
	def get(self, key, format): 
		"displays an entry"
		
	def post(self, key, format): 
		"adds an entry"
		
	def put(self, key, format): 
		"changes an entry"
		
	def delete(self, key, format): 
		"deletes an entry"
 
# webapp stuff
def main():
  application = webapp.WSGIApplication([
  	('/', HomeHandler),
  	('/feeds(?:/([^.]*))?(?:\.(.*))?', FeedHandler),
  	('/entries(?:/(.*))?(?:\.(.*))', EntryHandler)
  ], debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()
